/**
 * dom selecting !!
 */
function prev( elem ) {
	do {
        elem = elem.previousSibling;
        console.log(elem + ', ' + elem.nodeType);
    } while ( elem && elem.nodeType != 1 );
    return elem;
}


function next( elem ) {
    do {
        elem = elem.nextSibling;
    } while ( elem && elem.nodeType != 1 );
    return elem;
}


function first( elem ) {
    elem = elem.firstChild;
    return elem && elem.nodeType != 1 ?
        nextSibling( elem ) : elem;
}

function last( elem ) {
    elem = elem.lastChild;
    return elem && elem.nodeType != 1 ?
        prevSibling( elem ) : elem;
}

function parent( elem, num ) {
    num = num || 1;
    for ( var i = 0; i < num; i++ )
        if ( elem != null ) elem = elem.parentNode;
    return elem;
}

function attr(elem, name, value) {
    // Make sure that a valid name was provided
    if ( !name || name.constructor != String ) return '';
    
    // Figure out if the name is one of the weird naming cases

    /*
    1. 입력받은 값이 for 이면 htmlFor를 대입, 그렇지 않으면 undefined
        name = { 'for': 'htmlFor' }[name]
    2. 짧은 조건문
        http://goo.gl/xPn5K
        (불리언 표현식) || (불리언 표현식이 false일때 실행할 문장)
        name = { 'for' : 'htmlFor'}[name] || name;
    */
    name = { 'for': 'htmlFor', 'class': 'className' }[name] || name;

    // If the user is setting a value, also
    if ( value != null ) {
        // Set the quick way first
        elem[name] = value;

        // If we can, use setAttribute
        if ( elem.setAttribute )
            elem.setAttribute(name,value);
    }

    // Return the value of the attribute
    return elem[name] || elem.getAttribute(name) || '';
}

// Get a style property (name) of a specific element (elem)
function getStyle( elem, name ) {
    // If the property exists in style[], then it's been set recently (and is current)
    if (elem.style[name])
        return elem.style[name];

    // Otherwise, try to use IE's method
    else if (elem.currentStyle)
        return elem.currentStyle[name];

    // Or the W3C's method, if it exists
    else if (document.defaultView && document.defaultView.getComputedStyle) {
        // It uses the traditional 'text-align' style of rule writing, instead of textAlign
        name = name.replace(/([A-Z])/g,"-$1");
        name = name.toLowerCase();

        // Get the style object and get the value of the property (if it exists)
        var s = document.defaultView.getComputedStyle(elem,"");
        return s && s.getPropertyValue(name);

    // Otherwise, we're using some other browser
    } else
        return null;
}

// Find the X (Horizontal, Left) position of an element
function pageX(elem) {
    var p = 0;

    // We need to add up all of the offsets for every parent
    while ( elem.offsetParent ) {
        // Add the offset to the current count
        p += elem.offsetLeft;

        // and continue on to the next parent
        elem = elem.offsetParent;
    }

    return p;
}

// Find the Y (Vertical, Top) position of an element
function pageY(elem) {
    var p = 0;

    // We need to add up all the offsets for every parent
    while ( elem.offsetParent ) {
        // Add the offset to the current count
        p += elem.offsetTop;

        // and continue on to the next parent
        elem = elem.offsetParent;
    }

    return p;
}



// A function for hiding (using display) an element
function hide( elem ) {
    // Find out what it's current display state is
    var curDisplay = getStyle( elem, 'display' );

    //  Remember its display state for later
    if ( curDisplay != 'none' )
        elem.$oldDisplay = curDisplay;

    // Set the display to none (hiding the element)
    elem.style.display = 'none';
}

// A function for showing (using display) an element
function show( elem ) {
    // Set the display property back to what it use to be, or use
    // 'block', if no previous display had been saved
    elem.style.display = elem.$oldDisplay || 'block';
}



/**
 * event handling
 */
function addEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be attached");
  }
}

function stopBubble(e) {
    // If an event object is provided, then this is a non-IE browser
    if ( e )
        // and therefore it supports the W3C stopPropagation() method
        e.stopPropagation();
    else
        // Otherwise, we need to use the Internet Explorer way of cancelling event bubbling
        window.event.cancelBubble = true;
}
//stopBubble( e );

function stopDefault( e ) {
    // Prevent the default browser action (W3C)
    if ( e && e.preventDefault) {
    	e.preventDefault();
    // A shortcut for stoping the browser action in IE
    } else {
    	window.event.returnValue = false;
    }
    return false;
}
//return stopDefault( e );